
#include "file_list.h"

int file_list_recursion_scan(file_list_t  * file,const char *dir,unsigned int type)
{
	DIR *dirfd		 = NULL;
	struct dirent	 *entry_T;

	int 			 dirpath_length;

	char buff_T[sizeof(struct dirent) + 1024];
	char folder_path[1024];
	char filena_path[1024];


	if(!file)
		return -1;

	dirfd = opendir(dir);
	if(!dirfd){
		log_e("open dir error\n");
		return -1;
	}
	
	entry_T = (struct dirent *)buff_T;

	while (1)
	{
		entry_T = readdir(dirfd);
		if (!entry_T)
			break;

		if(entry_T->d_type == 4) //dir
		{
			if (!strcmp(entry_T->d_name, "."))
			{
				continue;
			}
			if (!strcmp(entry_T->d_name, ".."))
			{
				continue;
			}
			if (!strcmp_c(entry_T->d_name, "ALiDvr"))
			{
				continue;
			}		
			if (!strcmp_c(entry_T->d_name, "$RECYCLE.BIN"))
			{
				continue;
			}
			if (!strcmp_c(entry_T->d_name, "ALIDVRS2"))
			{
				continue;
			}			
			if (!strcmp_c(entry_T->d_name, "recycler"))
			{
				continue;
			}
			if (!strcmp_c(entry_T->d_name, "waller"))
			{
				continue;
			}						
			if (!strcmp_c(entry_T->d_name, "system volume information"))
			{
				continue;
			}
			
			if (!strcmp_c(entry_T->d_name, "System Volume Information"))
			{
				continue;
			}	
			if (!strcmp_c(entry_T->d_name, "thumbNail"))
			{
				continue;
			}	
			//*************************************************************
			#if 0
			if (!strcmp_c(entry_T->d_name, "1600x2400"))
			{
				continue;
			}	
			#endif
			if (!strcmp_c(entry_T->d_name, "2023-07-06"))
			{
				continue;
			}			
			if (!strcmp_c(entry_T->d_name, "test_00"))
			{
				continue;
			}			
			if (!strcmp_c(entry_T->d_name, "AI"))
			{
				continue;
			}
			//*************************************************************

			memset(folder_path,0,sizeof(folder_path));
			
			strcpy(folder_path,dir);
			strcat(folder_path,"/");
			strcat(folder_path,entry_T->d_name);
			
			log_i("folder_path=%s\n",folder_path);

			file_list_recursion_scan(file,folder_path,type);
			//*************************************************************
		}
		else //file
		{
			//*************************************************************
			
			memset(filena_path,0,sizeof(folder_path));

			strcpy(filena_path,dir);
			strcat(filena_path,"/");
			strcat(filena_path,entry_T->d_name);

			//log_i("filena_path=%s\n",filena_path);

			if(file->list_elem_type == MEDIA_TYPE_PHOTO)
			{
				if(__Valid_PhotoFileType(filena_path))
				{
					file_list_add_elem(file,dir,filena_path);
				}
			}
			else if(file->list_elem_type == MEDIA_TYPE_VIDEO)
			{
				if(__Valid_VideoFileType(filena_path))
				{
					file_list_add_elem(file,dir,filena_path);
				}
			}
			else if(file->list_elem_type == MEDIA_TYPE_MUSIC)
			{
				if(__Valid_MusicFileType(filena_path))
				{
					file_list_add_elem(file,dir,filena_path);
				}
			}
			else
			{
				continue;
			}
			//*************************************************************
		}
	}
	
	closedir(dirfd);
	dirfd = NULL;

	
	return 0;
}


int file_list_write_file(cJSON * root, const char* filename)
{
	int ret = -1;
	int fd  = -1;

	char *root_str = NULL;
	
	if(!root)
		return -1;

	if(!filename)
		return -1;

	root_str = cJSON_Print(root);
	if(!root_str)
		return -1;


	ret = remove(filename);

	fd = open(filename, O_CREAT|O_WRONLY);
	if(fd == (-1)){
		log_e("open file %s error\n",filename);
		return ;
	}

	write(fd,root_str,strlen(root_str));

	close(fd);
	fd = -1;

	return 0;
}


int file_list_add_cjson_elem(file_list_t  * list)
{
	slist_t* node;
	list_elem_t* elem = NULL;

	cJSON *r_para_t	= NULL;
	
	cJSON *f_para_t	= NULL;
	cJSON *f_info_t	= NULL;


	if (list == NULL) {
		log_e("page invalid page.\n");
		return -1;
	}

	if(slist_isempty(list->list_elem_head)){
		log_e("list empty.\n");
		return -1;
	}

	r_para_t = cJSON_CreateObject();
	cJSON_AddStringToObject(r_para_t, "id",   "filelist"); 
	cJSON_AddNumberToObject(r_para_t, "total", list->list_elem_num);

	f_para_t = cJSON_CreateArray();  		
	cJSON_AddItemToObject(r_para_t, "media", f_para_t);	

	
	slist_for_each(node, (list->list_elem_head))
	{
		elem = slist_entry(node, list_elem_t, elem_tail);
		if(elem){
			#if 0
			log_i("elem_name=%s\n",elem->elem_name);
			#endif

			f_info_t = cJSON_CreateObject();  
			cJSON_AddStringToObject(f_info_t, "fileName",elem->elem_name);
			cJSON_AddNumberToObject(f_info_t, "filesize",0);
			cJSON_AddItemToArray(f_para_t,f_info_t); 
		}
	}

	//***************************************************************************
	file_list_write_file(r_para_t,list->list_save_path);
	//***************************************************************************

	if(r_para_t != NULL){
	   cJSON_Delete(r_para_t);
	   r_para_t  = NULL;
	   f_para_t  = NULL;
	   f_info_t  = NULL;
	}	

	return 0;
}

int file_list_add_from_savefile(file_list_t  * list)
{
	int i = 0;
	FILE *fp = NULL;
	
	long long filelen = 0;
	char * root_str = NULL;

	if (list == NULL) {
		log_e("page invalid page.\n");
		return -1;
	}

	fp = fopen(list->list_save_path,"rb");
	if(fp == NULL){
		log_e("no file,%s\n",list->list_save_path);
		return -1;
	}
	
	fseek(fp, 0, SEEK_END);   
	filelen = ftell(fp);	  
	fseek(fp,0,SEEK_SET);	

	//log_i("filelen=%lld\n",filelen);
	//******************************************************
	if(filelen <= 0){
		fclose(fp);
		fp = NULL;

		system_para_default();
		system_para_save();
		return -1;
	}	
	//******************************************************
	root_str = malloc(filelen);
	if(root_str == NULL){
		fclose(fp);
		fp = NULL;
		return -1;
	}
	
	memset(root_str, '\0', filelen);
	fread(root_str,1,filelen,fp);
	fclose(fp);
	fp = NULL;
	//******************************************************
	list->list_r_para = cJSON_Parse(root_str);
	free(root_str);
	root_str = NULL;

	if(!list->list_r_para){
		log_e("para error \n");
		return -1;
	}
	//******************************************************
	cJSON *c_total = NULL;
	
	c_total = cJSON_GetObjectItem(list->list_r_para, "total");
	if(c_total){
		list->list_elem_num = c_total->valueint;
	}

	log_i("elem_num=%d\n",list->list_elem_num);
	//******************************************************
	list->list_f_para = cJSON_GetObjectItem(list->list_r_para, "media");	
	if(!list->list_f_para){
		log_e("f_para_t para error\n");
		return -1;
	}

	list->list_elem_num = cJSON_GetArraySize(list->list_f_para);
	//******************************************************
	#if 0
	for(i=0;i<total;i++)
	{
		cJSON *c_filename = NULL;

		f_info_t   = cJSON_GetArrayItem(f_para_t, i);
		c_filename = cJSON_GetObjectItem(f_info_t, "fileName");
		if(c_filename){
			file_list_add_elem(list,c_filename->valuestring,c_filename->valuestring);
		}
	}
	#endif
	//******************************************************


	//******************************************************

	return 0;
}
void* file_list_search_task(void *arg)
{
	long start_time = 0;
	long end_time   = 0;

	file_list_t  * file = NULL;
	file = (file_list_t *)(arg);

	log_i("dir=%s\n",file->list_dir);

	while(1)
	{
		if(!file->list_search_flag)
		{
			start_time = platform_get_microsecond();
			
			file_list_recursion_scan(file,file->list_dir,file->list_elem_type);
			file->list_search_flag = 1;

			end_time = platform_get_microsecond();

			//file_list_trav_elem(file);

			log_i("*********************************************************\n");
			log_i("*********************************************************\n");

			log_i("time=%ds,%dms,%dus\n",(end_time-start_time)/1000/1000,(end_time-start_time)/1000,(end_time-start_time));

			log_i("num=%d\n",file->list_elem_num);

			if((strlen(file->list_save_path) > 0)&&(file->list_elem_num > 0))
			{
				file_list_add_cjson_elem(file);
			}
			
			log_i("*********************************************************\n");
			log_i("*********************************************************\n");
		}
		else
		{
			usleep(1000);
		}
	}
}

file_list_t* file_list_create(file_list_t** list,const char* dir,media_type_e type,char * savepath)
{
	int ret  = 0;
	file_list_t* file = NULL;

	//log_i("file_list_t=%d\n",sizeof(file_list_t));

	file = (file_list_t *)malloc(sizeof(file_list_t));
	if(!file){
		log_e("create error\n");
		return NULL;
	}
	
	memset(file,0,sizeof(file_list_t));

	file->list_elem_num    = 0;
	file->list_elem_type   = type;
	file->list_search_flag = 0;
	
	file->list_r_para      = NULL;
	file->list_f_para      = NULL;

	sprintf(file->list_save_path,"%s",savepath);

	file->list_dir = (char *)malloc(MAX_FILE_PATH_SIZE);
	if(!file->list_dir){
		log_e("dir error\n");
		return NULL;
	}

	memset(file->list_dir,0,MAX_FILE_PATH_SIZE);

	strcpy(file->list_dir,dir);

	file->list_elem_head = (slist_t *)malloc(sizeof(slist_t));
	if(file->list_elem_head == NULL){
		log_e("heda error\n");
		return NULL;
	}

	slist_init(file->list_elem_head);

#if 0
	if(!file_list_add_from_savefile(file))
	{
		*list = file;
		return file;
	}
#endif

	ret=pthread_create(&(file->list_thread), NULL, file_list_search_task, file);
	if(ret != 0){
		log_e("thread error=%s\n",strerror(ret));
		return NULL;
	}
	
	*list = file;

	return file;		
}

int file_list_add_elem(file_list_t  * list,const char* dir,const char* fname)
{
	int i = 0;
	
	list_elem_t *elem = NULL;

	if (list == NULL) {
		log_e("invalid list.\n");
		return -1;
	}

	elem = (list_elem_t *)malloc(sizeof(list_elem_t));
	if(!elem){
		log_e("elem error\n");
		return -1;
	}
	
	elem->elem_type = 0;
	slist_init(&elem->elem_tail);
	
	elem->elem_name = (char *)malloc(MAX_FILE_PATH_SIZE);
	if(!elem->elem_name){
		log_e("elem_name error\n");
		free(elem);
		elem = NULL;
		return -1;
	}

	elem->elem_dir = (char *)malloc(MAX_FILE_PATH_SIZE);
	if(!elem->elem_dir){
		log_e("elem_name error\n");
		free(elem->elem_name);
		elem->elem_name = NULL;
		free(elem);
		elem = NULL;
		return -1;
	}

	strcpy(elem->elem_dir ,dir);
	strcpy(elem->elem_name,fname);

	slist_add_tail(list->list_elem_head ,&(elem->elem_tail));

	list->list_elem_num ++;

	return 0;
}

int file_list_del_elem(file_list_t  * list,list_elem_t *elem)
{
	int ret = 0;
	
	slist_t* node;

	if(list == NULL){
		log_e("invalid list.\n");
		return -1;
	}
	if(elem == NULL){
		log_e("obj invalid.\n");
		return -1;
	}

	if(slist_isempty(list->list_elem_head)){
		log_e("list empty.\n");
		return -1;
	}

	return 0;
}

int file_list_trav_elem(file_list_t  * list)
{
	slist_t* node;
	list_elem_t* elem = NULL;

	if (list == NULL) {
		log_e("page invalid page.\n");
		return -1;
	}

	if(slist_isempty(list->list_elem_head)){
		log_e("list empty.\n");
		return -1;
	}

	slist_for_each(node, (list->list_elem_head))
	{
		elem = slist_entry(node, list_elem_t, elem_tail);
		if(elem){
			#if 1
			//log_i("elem_dir =%s\n",elem->elem_dir);
			log_i("elem_name=%s\n",elem->elem_name);
			#endif
		}
	}

	return 0;
}

int file_list_get_filenum(file_list_t  * list)
{
	if(list == NULL){
		log_e("invalid list.\n");
		return 0;
	}

	return list->list_elem_num;
}

int file_list_get_filename(file_list_t  * list,char *fullpath,unsigned int index)
{
	int ret = -1;
	int search_index   = 0;

	slist_t*      node = NULL;
	list_elem_t*  elem = NULL;

	cJSON *f_info_t    = NULL;
	cJSON *c_filename  = NULL;

	if(!fullpath)
		return -1;

	if(list->list_f_para != NULL)
	{
		if(index > list->list_elem_num)
		{
			return -1;
		}

		f_info_t   = cJSON_GetArrayItem(list->list_f_para, index);
		c_filename = cJSON_GetObjectItem(f_info_t, "fileName");
		if(c_filename){
			strcpy(fullpath,c_filename->valuestring);
			ret = 0;
		}
	}
	else
	{
		if(list == NULL){
			log_e("invalid list.\n");
			return -1;
		}
		
		if(list->list_elem_head == NULL){
			log_e("list empty.\n");
			return -1;
		}
		
		if(slist_isempty(list->list_elem_head)){
			log_e("list empty.\n");
			return -1;
		}
		
		slist_for_each(node, (list->list_elem_head))
		{
			elem = slist_entry(node, list_elem_t, elem_tail);
			search_index++;
			if(search_index == index)
			{
				ret = 0;
				strcpy(fullpath,elem->elem_name);
				break;
			}
		}
	}

	return ret;
}


int file_list_delete(file_list_t  * list)
{

	 

	

	return 0;
}

















